import { Ref } from 'vue'
import { Widget } from '@/models'

/** 数字转千分位 */
function number2thousands(val: string) {
  if (!val) return ''

  // 是否负数
  const isNegative = val.startsWith('-')

  let [integer, decimal] = val.replace('-', '').split('.')

  if (!integer) return ''

  integer = integer
    .split('')
    .reverse()
    .reduce((prev, next, index) => (index % 3 ? next : next + ',') + prev)

  val = decimal ? `${integer}.${decimal}` : integer

  return isNegative ? `-${val}` : val
}

/** 过滤只保留数字内容 */
function filterNumber(val: string) {
  return (
    val
      // 去除数字、小数点、负号以外的字符
      .replace(/[^\d.-]/g, '')
      // 去除第一个小数点
      .replace(/^\./g, '')
      // 去除多余的小数点
      .replace(/(\.\d*)\./g, '$1')
      // 去除非第一个负号
      .replace(/(.+)-/g, '$1')
  )
}

/** 过滤输入的数字 */
function fixNumber(val: string, fixed: number) {
  val = filterNumber(val)

  if (fixed === 0) {
    // 整数去除小数点以后内容
    val = val.replace(/\.\d?/g, '')
  } else if (fixed > 0) {
    // 去除超出的小数点位数
    const reg = new RegExp(`(\\.\\d{${fixed}})\\d+`, 'g')
    val = val.replace(reg, '$1')
  }

  return val
}

/** 数字输入事件处理 */
export default function useNumberInput(data: Ref<Widget>) {
  return {
    /** 过滤输入的内容 @input @focus */
    filter() {
      const widget = data.value
      const { value: val, numberFixed: fixed, numberFixedLimit: limit } = widget

      widget.value = fixNumber(val as string, limit ? fixed : -1)
    },

    /** 格式化数字 @blur */
    format() {
      const widget = data.value
      let {
        value: val,
        text: { maxLength },
        numberFixed: fixed,
        numberFixedLimit: limit,
        thousands
      } = widget

      fixed = limit ? fixed : -1

      val = fixNumber(val as string, fixed)
        // 0 开始的数字，去除 0，`-0001 => -1`
        .replace(/^(-?)0+([1-9])/, '$1$2')

        // 开始的多个 0 保留一个，`000.1 => 0.1`
        .replace(/^0+/, '0')

        // 负数开始的多个 0 保留一个，`-000.1 => -0.1`
        .replace(/^-0+/, '-0')

        // 去除小数点后的 0 结尾
        .replace(/\.(.*[1-9])0+$/g, '.$1')

        // 去除小数点结尾
        .replace(/\.0*$/, '')

      if (fixed > 0 && val !== '') {
        // 数字补零
        const [, fixedNum] = val.split('.')

        // 当前小数点位数
        const _fixed = fixedNum?.length || 0

        // 当前文本长度
        const { length } = val

        // 小数点位数补零，不使用 `toFixed` 避免长数字科学计数
        if (_fixed === fixed) {
          // 位数一致，不处理
        } else if (_fixed) {
          // 小数点位数不够补零
          val = val.padEnd(length + fixed - _fixed, '0')
        } else {
          // 整数补小数点和零
          val = (val + '.').padEnd(length + 1 + fixed, '0')
        }
      }

      // 转千分位
      thousands && (val = number2thousands(val))

      if (val === '-') val = ''

      // 截取超长并删除末尾小数点逗号
      widget.value = val.slice(0, maxLength).replace(/(\.|,)$/g, '')
    }
  }
}
